package com.hqd.ch03.v25.aop.framework;

import com.hqd.ch03.v25.aware.Aware;
import com.hqd.ch03.v25.core.Ordered;
import com.hqd.ch03.v25.utils.ClassUtils;
import com.hqd.ch03.v25.utils.ObjectUtils;

import java.io.Closeable;

public class ProxyProcessorSupport extends ProxyConfig implements Ordered, AopInfrastructureBean {
    private int order = Ordered.LOWEST_PRECEDENCE;

    private ClassLoader proxyClassLoader = Thread.currentThread().getContextClassLoader();

    @Override
    public int getOrder() {
        return this.order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    protected ClassLoader getProxyClassLoader() {
        return this.proxyClassLoader;
    }

    /**
     * 计算可代理接口
     *
     * @param beanClass
     * @param proxyFactory
     */
    protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
        Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
        boolean hasReasonableProxyInterface = false;
        for (Class<?> ifc : targetInterfaces) {
            /**
             * 过滤不必要的接口
             */
            if (!isConfigurationCallbackInterface(ifc) && ifc.getMethods().length > 0) {
                hasReasonableProxyInterface = true;
                break;
            }
        }
        /**
         * 如果存在可代理接口，则使用接口代理
         * 不存在，则用类代理
         *
         */
        if (hasReasonableProxyInterface) {
            for (Class<?> ifc : targetInterfaces) {
                proxyFactory.addInterface(ifc);
            }
        } else {
            proxyFactory.setProxyTargetClass(true);
        }
    }

    protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
        return (Closeable.class == ifc ||
                AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
    }
}
